package com.demo.modules.stock.util;

import java.io.IOException;
import java.util.*;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.ParserConfig;
import com.demo.modules.stock.entity.StockDayEntity;
import com.demo.modules.stock.entity.StockIndexEntity;
import com.demo.modules.stock.entity.StockInfoEntity;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import com.google.gson.JsonObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class StockUtils {

    protected static final Logger logger = LoggerFactory.getLogger(StockUtils.class);

    /**
     * 转成echarts的K线图格式
     * 数据意义：开盘(open)，收盘(close)，最低(lowest)，最高(highest)
     *
     * @return 格式:[['2013/6/3', 2300.21,2299.25,2294.11,2313.43],['2013/6/4', 2297.1,2272.42,2264.76,2297.1]]
     */
    public static ArrayList<Object> covertToKLine(List<StockDayEntity> list) {
        ArrayList<Object> outerList = new ArrayList<>(3000);
        ArrayList<Object> innerList;
        for (StockDayEntity tmp : list) {
            innerList = new ArrayList<>();
            innerList.add(DateUtil.format(tmp.getDayDate(), "yyyy-MM-dd"));
            innerList.add(tmp.getOpenPrice());
            innerList.add(tmp.getClosePrice());
            innerList.add(tmp.getLowest());
            innerList.add(tmp.getHighest());
            outerList.add(innerList);
        }
        return outerList;
    }

    public static ArrayList<Object> covertToEcharts2(Object list) {
        ArrayList<Object> outerList = new ArrayList<>(3000);
        ArrayList<Object> innerList;
        List<StockIndexEntity> stockInfoEntityList = (List<StockIndexEntity>) list;
        for (StockIndexEntity tmp : stockInfoEntityList) {
            innerList = new ArrayList<>();
            innerList.add(DateUtil.format(tmp.getDayDate(), "yyyy-MM-dd"));
            innerList.add(tmp.getClosePrice());
            outerList.add(innerList);
        }
        return outerList;
    }

    /**
     * 从百度获取股票历史价格
     *
     * @param code 例:https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?resource_id=8188&from_mid=1&query=002456%20%E8%82%A1%E7%A5%A8&eprop=year&sitesign=eecc3219f38c7f9c62f22e7a8a450870"
     * @return 股票收盘价格, 格式[["2017-01-03",0.897],["2017-01-04",0.904]]
     */
    public static List<List<String>> getStockClosePriceByBaidu(String code) {
        String url;
        if (code.equals("-1")) {
            //上证指数
            url = "https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?resource_id=8190&from_mid=1&query=%E4%B8%8A%E8%AF%81%E6%8C%87%E6%95%B0&eprop=year";
        } else {
            url = "https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?resource_id=5353&all=1&pointType=string&group=quotation_kline_ab&ktype=1&query=" + code + "&code=" + code + "&ktype=1&word=" + code + "&format=json&from_mid=1&oe=utf-8&dsp=pc&tn=wisexmlnew&need_di=1&all=1&query=" + code + "&eprop=dayK&euri=undefined&request_type=sync&stock_type=ab&sid=33814_31253_34004_33607_26350_22157";
        }

        String response;
        try {
            response = HttpRequest.get(url).timeout(3000).execute().body();
        } catch (Exception e) {
            logger.error("爬取股票价格失败!");
            e.printStackTrace();
            return null;
        }

        List<List<String>> result = new ArrayList<>(200);

        try {
            ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
            JSONObject jsonObject = JSON.parseObject(response);

            JSONObject r = jsonObject.getJSONArray("Result").getJSONObject(0).getJSONObject("DisplayData")
                    .getJSONObject("resultData")
                    .getJSONObject("tplData")
                    .getJSONObject("result");

            //股票日期和价格
            String stockPriceStr = r.get("p").toString();

            String[] stockPriceArray = stockPriceStr.split(";");
            for (String p : stockPriceArray) {
                String[] tmp = p.split(",");
                List<String> tmpList = new ArrayList<>();
                //股票交易日期
                tmpList.add(tmp[0].replaceAll("/", "-"));
                //开盘价格
                tmpList.add(tmp[1]);
                //收盘价格
                tmpList.add(tmp[4]);
                //最高价
                tmpList.add(tmp[2]);
                //最低价
                tmpList.add(tmp[3]);
                result.add(tmpList);
            }
        } catch (Exception e) {
            logger.error("截取股票价格失败!");
            e.printStackTrace();
            return null;
        }

        logger.info("截取股票价格成功!");
        return result;
    }

    /**
     * 从新浪获取每日股票价格
     *
     * @param code 例:http://hq.sinajs.cn/list=sz000002,返回格式var hq_str_sz000002="万 科Ａ,28.050,28.020,28.030,28.290,27.740,28.030,28.040,68434585,1913388242.740,186381,28.030,77500,28.020,14800,28.010,114400,28.000,26200,27.990,16200,28.040,22300,28.050,14700,28.060,6200,28.070,11700,28.080,2020-10-09,15:00:03,00";
     *             数值依次是今日开盘价、昨日收盘价、当前价、今日最高价、今日最低价
     * @return 股票价格, 依次是开盘、收盘、最高、最低、日期
     */
    public static String[] getStockPriceBySina(String code) {
        String url = "http://hq.sinajs.cn/list=" + code;
        String[] price = new String[5];
        try {
            String response = GetResponse.getResponse(url);
            response = response.substring(response.indexOf(",") + 1, response.length() - 2);
            String[] tmp = response.split(",");
           /* for (String t : tmp) {
                System.out.println(t);
            }*/
            price[0] = tmp[0];
            price[1] = tmp[2];
            price[2] = tmp[3];
            price[3] = tmp[4];
            price[4] = tmp[29];
            /*for (String t : price) {
                System.out.println(t);
            }*/
        } catch (Exception e) {
            logger.error("爬取股票价格失败!");
            e.printStackTrace();
            return null;
        }

        logger.debug("截取股票价格成功!");
        return price;
    }

    /**
     * 从小熊网站获取股票历史价格
     * 地址:https://api.doctorxiong.club/v1/stock/detail?code=sz002263&year=3获取股票价格
     * https://www.doctorxiong.club/
     *
     * @param code 股票编码
     * @return 股票历史价格数组, 元素依次是股票日期、开盘价、收盘价、最高价、最低价, 格式[["2017-01-03",0.897],["2017-01-04",0.904]]
     */
    public static List<List<String>> getStockPriceByBear(String code, int year) {
//        String url = "https://api.doctorxiong.club/v1/stock/detail?code=" + code + "&year=" + year;
        String startDate = DateUtil.formatDate(DateUtil.offset(new Date(), DateField.YEAR, -1 * year));
        String url = "https://api.doctorxiong.club/v1/stock/kline/day?token=MfEfZ2E3aX&code=" + code + "&startDate=" + startDate + "&type=0";
        System.out.println(url);
        String response;
        try {
            response = HttpRequest.get(url).timeout(3000).execute().body();
        } catch (Exception e) {
            logger.error("爬取股票价格失败!");
            e.printStackTrace();
            return null;
        }

        List<List<String>> result = new ArrayList<>(200);

        try {
            JSONObject jsonObject = JSON.parseObject(response);
            JSONArray jsonArray = jsonObject.getJSONArray("data");
            JSONArray tmp = null;

            for (Object o : jsonArray) {
                tmp = (JSONArray) o;

                List<String> tmpList = new ArrayList<>();
                //股票交易日期
                tmpList.add(tmp.get(0).toString());
                //开盘价格
                tmpList.add(tmp.get(1).toString());
                //收盘价格
                tmpList.add(tmp.get(2).toString());
                //最高价
                tmpList.add(tmp.get(3).toString());
                //最低价
                tmpList.add(tmp.get(4).toString());
                result.add(tmpList);
            }

        } catch (Exception e) {
            logger.error("截取股票价格失败!" + url);
            e.printStackTrace();
            return null;
        }

        logger.info("截取股票价格成功!");
        return result;
    }

    //获取上交所的股票板块
    public static List<String> getIndustryCode(String type) {
        List<String> codeList = new ArrayList<>();
        RandomUtil.randomInt(0, 100000);
        String callback = "jsonpCallback" + RandomUtil.randomInt(0, 100000);
        String url = "http://query.sse.com.cn/security/stock/queryIndustryIndex.do?&jsonCallBack=" + callback + "&isPagination=false&csrcCode=" + type;
        String result = HttpRequest.get(url)
                .header(Header.ACCEPT, "*/*")
                .header(Header.ACCEPT_ENCODING, "gzip, deflate")
                .header(Header.ACCEPT_LANGUAGE, "zh-CN,zh;q=0.9")
                .header(Header.CONNECTION, "keep-alive")
                .header(Header.HOST, "query.sse.com.cn")
                .header(Header.REFERER, "http://www.sse.com.cn/assortment/stock/areatrade/trade/detail.shtml?csrcCode=B")
                .header(Header.USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36")
                .execute().body();
        result = result.substring(result.indexOf("(") + 1, result.length() - 1);
        JSONArray jsonArray = JSON.parseObject(result).getJSONArray("result");
        for (Object o : jsonArray) {
            codeList.add(((JSONObject) o).getString("companycode"));
        }
        return codeList;
    }

    public static void main(String[] args) throws IOException {

        //从小熊网站获取股票价格
//        System.out.println(getStockPriceByBear("600363", 7));

        //从百度获取一年内的股票价格
        System.out.println(getStockClosePriceByBaidu("605303"));

        System.out.println(JSON.toJSONString(getStockPriceBySina("sz300001")));
//        System.out.println(getStockPriceBySina("sh601939"));
//        System.out.println(getStockPriceBySina("sz000004"));

    }
}
